/* simulate a tandem queue and record the relationship between runtime 
 * and number of servers (queues) in the system
*/

#include "csim.h"
#include <stdio.h>

#define NARS 3			//The number of customers per run
#define IATM 2.0			//The expected customer interarrival time
#define SVTM 1.0			//The expected service time
#define NMAX 2000			//Number of queues in a tandem queue

FACILITY f;		/*pointer for facility */
EVENT done;		/*pointer for counter */
TABLE tbl;		/*pointer for table */
QTABLE qtbl;	/*pointer for qhistogram */
int cnt;		/*number of active tasks*/
FILE *fp;

void cust();
void theory();

void sim()						/*1st process - named sim */
{
	int i, d, k;
	double runtime[NMAX];			//record the runtime for each N
	float start;
    int qamount;
	
	fp = fopen("csim.out", "w");
	set_output_file(fp);
	set_trace_file(fp);
	set_error_file(fp);
	set_model_name("tandem queue");
	create("sim");				/*required create statement*/
	f = facility("facility");		/*initialize facility*/
	done = event("done");			/*initialize event*/
	tbl = table("resp tms");		/*initialize table */
	qtbl = qhistogram("num in sys", 10l);	/*initialize qhistogram*/
	
	for(qamount = 1; qamount*100 < NMAX; qamount ++)
	{
		runtime[qamount*100] = 0;
		start = cputime();
		cnt = NARS;							/*initialize cnt*/
		for(i = 1; i <= NARS; i++) {
			hold(expntl(IATM));				/*hold interarrival*/
			cust(qamount*100);				/*initiate process cust*/
		}
		wait(done);				/*wait until all done*/
		runtime[qamount*100] = (double)(cputime()-start);
	}
	
	printf("\r\nN vs. run time (one '*' = 10 msec)");
	for (d=1; d*100<NMAX; d++){
		printf("\nN=%5d |",d*100);
		for (k=0; k*0.01 < runtime[d*100]; k++)
			printf("*");
	}
	printf("\r\n\r\n");
}

void cust(int snum)						/*process customer*/
{
	TIME t1;
	int i;
 
	create("cust");				/*required create statement*/

	t1 = clock;					/*time of request */
	note_entry(qtbl);			/*note arrival */
	for(i = 0; i < snum; i++) {
		reserve(f);					/*reserve facility f*/
		hold(expntl(SVTM));		/*hold service time*/
		release(f);					/*release facility f*/
	}
	record(clock-t1, tbl);		/*record response time*/
	note_exit(qtbl);			/*note departure */
	cnt--;						/*decrement cnt*/
	if(cnt == 0)
		set(done);				/*if last arrival, signal*/
}
